home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / manchest.lha / MANCHESTER / manchester / 2.3 / removing-active-subviews.st < prev    next >
Text File  |  1993-07-24  |  5KB  |  154 lines

  1. "    NAME        removing-active-subviews
  2.     AUTHOR        neild@cs.man.ac.uk
  3.     CONTRIBUTOR    neild@cs.man.ac.uk
  4.     FUNCTION      allows views whose controllers are active to be removed
  5.     ST-VERSIONS    2.2 2.3
  6.     PREREQUISITES     
  7.     CONFLICTS     
  8.     DISTRIBUTION    global
  9.     VERSION        1.1
  10.     DATE        15 Mar 1990
  11. SUMMARY    removing-active-subviews
  12. In the search for an ever better user interface I built a view structure
  13. where one of the views had a sub view removed, and a new one added, as a
  14. result of a menu command initiated from the removed view (before it was
  15. removed :-) ). It all fell apart because the method in the model that
  16. causes the changing of the views returns to the controller of, a now
  17. released, view whose super view is also not what it was. The following
  18. changes alleviate this problem by providing a mechanism that allows control
  19. to jump up the stack to a 'higher' controller with a view whose super view
  20. hasn't changed, and thus hasn't been removed or released.
  21.  
  22. To use this mechanism, either pass the controller to the model and then
  23. send it Controller|exitControlLoop once any actions that cause views to be
  24. removed are complete, or rely on the test in
  25. Controller|controlInitialise. Reimplement Controller|controlToNextLevel if
  26. you don't want control to exit to the ControlManager, i.e. for the
  27. controller of the view whose sub views are changed dynamically.
  28.  
  29. This takes a while to file in as all subclasses of Controller are recompiled.
  30. This mechanism may be replaced for 2.5 by one based on exceptions.
  31.  
  32. "!
  33. Object subclass: #Controller
  34.     instanceVariableNames: 'model view sensor exitBlock '
  35.     classVariableNames: ''
  36.     poolDictionaries: ''
  37.     category: 'Interface-Framework'!
  38.  
  39. | ebi |
  40. Controller withAllSubclasses do: [ :cc | 
  41.     ebi _ cc allInstVarNames indexOf: 'exitBlock'.
  42.     cc allInstancesDo: [ :ci |
  43.         ci instVarAt: ebi put: [] ] ]!
  44.  
  45. !Controller methodsFor: 'basic control sequence'!
  46.  
  47. startUpWithExternalExitBy: anExitBlock
  48.     "Give control to the receiver. The default control sequence is to initialize
  49.  
  50.     (see Controller|controlInitialize), to loop (see Controller|controlLoop),
  51.  and 
  52.     then to terminate (see Controller|controlTerminate). After this sequence,
  53.  
  54.     control is returned to the sender of Control|startUp:. The receiver's
  55.  control 
  56.     sequence is used to coordinate the interaction of its view and model.
  57.  In general, 
  58.     this consists of polling the sensor for user input, testing the input
  59.  with respect 
  60.     to the current display of the view, and updating the model to reflect
  61.  intended 
  62.     changes. anExitBlock allows for an abnormal exit from the control loop
  63.  (see
  64.     Controller|startUp and Controller|exitControlLoop). This is necessary
  65.  if an
  66.     action from this controller, or that of a sub view, causes the view
  67.  to change
  68.     its top view or be released."
  69.  
  70.     exitBlock _ anExitBlock.
  71.     self controlInitialize.
  72.     self controlLoop.
  73.     self controlTerminate!
  74.  
  75. exitControlLoop
  76.     "Cause control to be returned immediately to some higher controller
  77.  as defined
  78.     by the exitBlock (see Controller|controlToNextLevel and Controller|startUp).
  79.  
  80.     This method is not expected to return to its sender. It allows the
  81.  suspended
  82.     method contexts of Controllers whose views have been removed to be
  83.  lost.
  84.     This is necessary if the controller of some sub view in a view hierarchy
  85.  
  86.     initiates an action that causes one of its super views to be removed
  87.  from
  88.     the hierarchy, e.g. as a result of a menu action in the controller's
  89.  model."
  90.  
  91.     exitBlock isNil ifTrue: [ self error: 'exit block not defined' ].
  92.     exitBlock value! !
  93.  
  94. !NoController methodsFor: 'basic control sequence'!
  95.  
  96. startUpWithExternalExitBy: anExitBlock
  97.     "I do nothing."
  98.     ^self! !
  99.  
  100. !Controller methodsFor: 'basic control sequence'!
  101.  
  102. startUp
  103.     "Give control to the receiver. The default control sequence is to initialize
  104.  
  105.     (see Controller|controlInitialize), to loop (see Controller|controlLoop),
  106.  and 
  107.     then to terminate (see Controller|controlTerminate). After this sequence,
  108.  
  109.     control is returned to the sender of Control|startUp. The receiver's
  110.  control 
  111.     sequence is used to coordinate the interaction of its view and model.
  112.  In general, 
  113.     this consists of polling the sensor for user input, testing the input
  114.  with respect 
  115.     to the current display of the view, and updating the model to reflect
  116.  intended 
  117.     changes."
  118.  
  119.     self startUpWithExternalExitBy: [ ^self ]! !
  120.  
  121. !Controller methodsFor: 'control defaults'!
  122.  
  123. controlToNextLevel
  124.     "Pass control to the next control level, that is, to the Controller
  125.  of a subView of 
  126.     the receiver's view if possible. The receiver finds the subView (if
  127.  any) whose controller    
  128.     wants control and sends that controller the message startUpWithExternalExitBy:.
  129.  If
  130.     that controller is required to exit from its control loop by Controller|exitControlLoop
  131.  
  132.     then this also exits its control loop."
  133.  
  134.     | aView |
  135.     aView _ view subViewWantingControl.
  136.     aView ~~ nil ifTrue: [ aView controller
  137.         startUpWithExternalExitBy: [ view notNil ifTrue: [ self controlTerminate
  138.  ]. self exitControlLoop ] ]! !
  139.  
  140. !Controller methodsFor: 'basic control sequence'!
  141.  
  142. controlInitialize
  143.     "Sent as part of the standard control sequence. It provides 
  144.     a place in the standard control sequence for initializing the receiver
  145.  
  146.     (taking into account the current state of its model and view). It should
  147.  be 
  148.     redefined in subclasses to perform some specific action."
  149.  
  150.     view isNil ifTrue: [ self exitControlLoop ].
  151.     ^self! !
  152.  
  153.  
  154.